<template>
  <div class="publish-container" 
       @keydown="handleKeydown" 
       tabindex="0">
    <div class="publish-header">
      <div class="header-content">
        <div class="header-left">
          <!-- 移除标题输入框 -->
        </div>
        <div class="header-right">
          <a-button @click="handleCancel">取消</a-button>
          <a-button type="primary" :loading="publishing" @click="handlePublish">
            发布
          </a-button>
        </div>
      </div>
    </div>

    <div class="editor-container">
      <div class="editor-toolbar">
        <div class="toolbar-left">
          <a-button-group class="format-group">
            <a-button @click="insertText('# ')" title="标题1">H1</a-button>
            <a-button @click="insertText('## ')" title="标题2">H2</a-button>
            <a-button @click="insertText('### ')" title="标题3">H3</a-button>
          </a-button-group>

          <a-divider type="vertical" />

          <a-button-group class="format-group">
            <a-button @click="insertText('**', '**')" title="加粗">
              <a-icon type="bold" />
            </a-button>
            <a-button @click="insertText('*', '*')" title="斜体">
              <a-icon type="italic" />
            </a-button>
            <a-button @click="insertText('~~', '~~')" title="删除线">
              <a-icon type="strikethrough" />
            </a-button>
          </a-button-group>

          <a-divider type="vertical" />

          <a-button-group class="format-group">
            <a-button @click="insertText('- ')" title="无序列表">
              <a-icon type="unordered-list" />
            </a-button>
            <a-button @click="insertText('1. ')" title="有序列表">
              <a-icon type="ordered-list" />
            </a-button>
            <a-button @click="insertText('> ')" title="引用">
              <a-icon type="menu-unfold" />
            </a-button>
          </a-button-group>

          <a-divider type="vertical" />

          <a-button-group class="format-group">
            <a-button @click="insertText('```\n', '\n```')" title="代码块">
              <a-icon type="code" />
            </a-button>
            <a-button @click="insertText('`', '`')" title="行内代码">
              <span style="font-family: monospace;">{}</span>
            </a-button>
            <a-upload
              name="file"
              :action="uploadUrl"
              :headers="uploadHeaders"
              :show-upload-list="false"
              @change="handleUploadChange"
              accept="image/*"
            >
              <a-button>
                <a-icon type="picture" /> 插入图片
              </a-button>
            </a-upload>
          </a-button-group>
        </div>

        <div class="toolbar-right">
          <a-button-group>
            <a-button @click="toggleSplit" :type="isSplit && isPreview ? 'primary' : 'default'" title="分屏预览">
              <a-icon type="column-width" />
            </a-button>
            <a-button @click="togglePreview" :type="isPreview && !isSplit ? 'primary' : 'default'" title="全屏预览">
              <a-icon type="eye" />
            </a-button>
          </a-button-group>
          <a-divider type="vertical" />
          <a-button @click="showShortcutHelp = true" title="快捷键帮助">
            <a-icon type="question-circle" />
          </a-button>
        </div>
      </div>

      <div class="editor-main" :class="{ 'preview-mode': isPreview, 'split-mode': isSplit }">
        <div class="editor-area" :class="{ 'hidden': isPreview && !isSplit }">
          <a-textarea
            v-model="content"
            :rows="20"
            placeholder="开始创作..."
            @input="handleInput"
            @paste="handlePaste"
          />
        </div>
        <div class="preview-area" :class="{ 'hidden': !isPreview }">
          <div class="markdown-content" v-html="renderedContent"></div>
        </div>
      </div>
    </div>

    <div class="back-to-top" v-show="showBackTop" @click="scrollToTop">
      <a-icon type="up" />
    </div>

    <!-- 快捷键帮助弹窗 -->
    <a-modal
      title="Markdown 快捷键帮助"
      :visible="showShortcutHelp"
      @cancel="showShortcutHelp = false"
      :footer="null"
      width="600px"
    >
      <div class="shortcut-help">
        <table class="shortcut-table">
          <thead>
            <tr>
              <th>功能</th>
              <th>快捷键</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(shortcut, key) in shortcutList" :key="key">
              <td>{{ shortcut.name }}</td>
              <td><kbd>{{ shortcut.key }}</kbd></td>
            </tr>
          </tbody>
        </table>
      </div>
    </a-modal>
  </div>
</template>

<script>
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-dark.css'
import DOMPurify from 'dompurify'
import request from '@/utils/request'

export default {
  name: 'MomentPublish',
  data() {
    return {
      content: '',
      imageUrl: '',
      publishing: false,
      isPreview: true,
      isSplit: true,
      uploadUrl: 'http://localhost:4000/oss/upload',
      uploadHeaders: {
        'sa-token': localStorage.getItem('token')
      },
      showBackTop: false,
      showShortcutHelp: false,
      shortcuts: {
        'ctrl+b': { prefix: '**', suffix: '**' },
        'ctrl+i': { prefix: '*', suffix: '*' },
        'ctrl+k': { prefix: '[', suffix: '](url)' },
        'ctrl+u': { prefix: '<u>', suffix: '</u>' },
        'ctrl+`': { prefix: '`', suffix: '`' },
        'ctrl+shift+`': { prefix: '```\n', suffix: '\n```' },
        'ctrl+shift+i': { prefix: '![图片描述](', suffix: ')' },
        'ctrl+shift+b': { prefix: '> ', suffix: '' },
        'ctrl+shift+l': { prefix: '1. ', suffix: '' },
        'ctrl+l': { prefix: '- ', suffix: '' },
        'ctrl+1': { prefix: '# ', suffix: '' },
        'ctrl+2': { prefix: '## ', suffix: '' },
        'ctrl+3': { prefix: '### ', suffix: '' },
      },
      shortcutList: [
        { name: '加粗', key: 'Ctrl + B' },
        { name: '斜体', key: 'Ctrl + I' },
        { name: '插入链接', key: 'Ctrl + K' },
        { name: '下划线', key: 'Ctrl + U' },
        { name: '行内代码', key: 'Ctrl + `' },
        { name: '代码块', key: 'Ctrl + Shift + `' },
        { name: '插入图片', key: 'Ctrl + Shift + I' },
        { name: '引用', key: 'Ctrl + Shift + B' },
        { name: '有序列表', key: 'Ctrl + Shift + L' },
        { name: '无序列表', key: 'Ctrl + L' },
        { name: '一级标题', key: 'Ctrl + 1' },
        { name: '二级标题', key: 'Ctrl + 2' },
        { name: '三级标题', key: 'Ctrl + 3' },
      ]
    }
  },
  computed: {
    renderedContent() {
      marked.setOptions({
        highlight: function(code, lang) {
          if (lang && hljs.getLanguage(lang)) {
            try {
              return hljs.highlight(code, { language: lang }).value
            } catch (err) {
              console.log(err)
            }
          }
          return hljs.highlightAuto(code).value
        },
        breaks: true,
        gfm: true
      })
      return DOMPurify.sanitize(marked(this.content || ''))
    }
  },
  mounted() {
    window.addEventListener('scroll', this.handleScroll)
  },
  beforeDestroy() {
    window.removeEventListener('scroll', this.handleScroll)
  },
  methods: {
    handleInput() {
      const textarea = document.querySelector('.editor-area textarea')
      if (textarea) {
        textarea.style.height = 'auto'
        textarea.style.height = textarea.scrollHeight + 'px'
      }
    },
    insertText(prefix, suffix = '') {
      const textarea = document.querySelector('.editor-area textarea')
      const start = textarea.selectionStart
      const end = textarea.selectionEnd
      const selected = this.content.substring(start, end)
      
      if (prefix === '[' && suffix === '](url)' && selected) {
        this.content = this.content.substring(0, start) +
          `[${selected}](url)` +
          this.content.substring(end)
        
        this.$nextTick(() => {
          const urlStart = start + selected.length + 2
          textarea.focus()
          textarea.selectionStart = urlStart + 1
          textarea.selectionEnd = urlStart + 4
        })
        return
      }
      
      if ((prefix === '- ' || prefix === '1. ' || prefix === '> ') && 
          (start === 0 || this.content[start-1] === '\n')) {
        this.content = this.content.substring(0, start) +
          prefix.trimLeft() + selected +
          this.content.substring(end)
      } else {
        this.content = this.content.substring(0, start) +
          prefix + selected + suffix +
          this.content.substring(end)
      }
      
      this.$nextTick(() => {
        textarea.focus()
        if (selected) {
          textarea.selectionStart = start + prefix.length
          textarea.selectionEnd = start + prefix.length + selected.length
        } else {
          textarea.selectionStart = start + prefix.length
          textarea.selectionEnd = start + prefix.length
        }
      })
    },
    togglePreview() {
      if (this.isPreview && !this.isSplit) {
        this.isSplit = true
      } else if (this.isPreview && this.isSplit) {
        this.isPreview = false
        this.isSplit = true
      } else {
        this.isPreview = true
      }
    },
    toggleSplit() {
      if (this.isSplit) {
        this.isPreview = false;
        this.isSplit = false;
      } else {
        this.isPreview = true;
        this.isSplit = true;
      }
    },
    beforeUpload(file) {
      const isImage = file.type.startsWith('image/')
      if (!isImage) {
        this.$message.error('只能上传图片文件！')
        return false
      }
      const isLt5M = file.size / 1024 / 1024 < 5
      if (!isLt5M) {
        this.$message.error('图片必须小于 5MB！')
        return false
      }
      return true
    },
    handleUploadChange(info) {
      if (info.file.status === 'done') {
        const response = info.file.response
        if (response.code === 200) {
          const imageMarkdown = `![图片](${response.content})`
          const textarea = document.querySelector('.editor-area textarea')
          const start = textarea.selectionStart
          const end = textarea.selectionEnd
          this.content = this.content.substring(0, start) + imageMarkdown + this.content.substring(end)
          this.$message.success('上传成功')
        } else {
          this.$message.error('上传失败')
        }
      } else if (info.file.status === 'error') {
        this.$message.error('上传失败')
      }
    },
    handleCancel() {
      this.$router.push('/social')
    },
    async handlePublish() {
      if (!this.content.trim()) {
        this.$message.warning('请输入动态内容')
        return
      }
      
      this.publishing = true
      try {
        const res = await request.post('/life/moment/add', {
          content: this.content,
          imageUrl: this.imageUrl
        })
        
        if (res.code === 200) {
          this.$message.success('发布成功')
          this.$router.push('/social')
        }
      } catch (error) {
        this.$message.error('发布失败')
      } finally {
        this.publishing = false
      }
    },
    handleScroll() {
      this.showBackTop = window.pageYOffset > 300
    },
    scrollToTop() {
      window.scrollTo({
        top: 0,
        behavior: 'smooth'
      })
    },
    handleKeydown(e) {
      const key = [
        e.ctrlKey ? 'ctrl' : '',
        e.shiftKey ? 'shift' : '',
        e.key.toLowerCase()
      ].filter(Boolean).join('+')
      
      const shortcut = this.shortcuts[key]
      if (shortcut) {
        e.preventDefault()
        this.insertText(shortcut.prefix, shortcut.suffix)
      }
    },
    handlePaste(e) {
      const items = (e.clipboardData || e.originalEvent.clipboardData).items;
      let blob = null;

      for (const item of items) {
        if (item.type.indexOf('image') === 0) {
          e.preventDefault();
          blob = item.getAsFile();
          break;
        }
      }

      if (blob) {
        // 创建临时的loading文本
        const textarea = document.querySelector('.editor-area textarea');
        const start = textarea.selectionStart;
        const end = textarea.selectionEnd;
        const loadingText = '![图片上传中...]()'
        
        // 插入loading文本
        this.content = this.content.substring(0, start) +
          loadingText +
          this.content.substring(end);
        
        // 保存插入位置信息
        const insertPosition = {
          start,
          length: loadingText.length
        };

        // 创建FormData对象
        const formData = new FormData();
        formData.append('file', blob);

        // 上传图片
        const xhr = new XMLHttpRequest();
        xhr.open('POST', this.uploadUrl, true);
        xhr.setRequestHeader('sa-token', this.uploadHeaders['sa-token']);

        xhr.onload = () => {
          if (xhr.status === 200) {
            const response = JSON.parse(xhr.responseText);
            if (response.code === 200) {
              // 替换loading文本为实际图片
              const imageMarkdown = `![图片](${response.content})`;
              this.content = this.content.substring(0, insertPosition.start) +
                imageMarkdown +
                this.content.substring(insertPosition.start + insertPosition.length);
              
              this.$message.success('图片上传成功');
            } else {
              // 移除loading文本
              this.content = this.content.substring(0, insertPosition.start) +
                this.content.substring(insertPosition.start + insertPosition.length);
              this.$message.error('图片上传失败');
            }
          } else {
            // 移除loading文本
            this.content = this.content.substring(0, insertPosition.start) +
              this.content.substring(insertPosition.start + insertPosition.length);
            this.$message.error('图片上传失败');
          }
        };

        xhr.onerror = () => {
          // 移除loading文本
          this.content = this.content.substring(0, insertPosition.start) +
            this.content.substring(insertPosition.start + insertPosition.length);
          this.$message.error('图片上传失败');
        };

        xhr.send(formData);
      }
    },
  }
}
</script>

<style scoped>
.publish-container {
  min-height: 100vh;
  background-color: #fff;
  outline: none;
}

.publish-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background-color: #fff;
  border-bottom: 1px solid #e4e6eb;
}

.header-content {
  max-width: 1200px;
  margin: 0 auto;
  height: 60px;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.header-right {
  display: flex;
  gap: 12px;
}

.editor-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 84px 24px 24px;
}

.editor-toolbar {
  padding: 8px 0;
  border-bottom: 1px solid #e4e6eb;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #fff;
  position: sticky;
  top: 60px;
  z-index: 99;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.format-group {
  display: flex;
  gap: 4px;
}

.format-group .ant-btn {
  border: none;
  background: transparent;
  padding: 6px 8px;
  height: 32px;
}

.format-group .ant-btn:hover {
  background: #f4f5f5;
  color: #1890ff;
}

.editor-main {
  margin-top: 24px;
  display: flex;
  gap: 24px;
}

.editor-area {
  flex: 1;
  transition: all 0.3s ease;
}

.preview-area {
  flex: 1;
  transition: all 0.3s ease;
}

.editor-area.hidden,
.preview-area.hidden {
  display: none;
}

.preview-mode:not(.split-mode) .preview-area {
  flex: 1;
  max-width: 768px;
  margin: 0 auto;
  padding: 0 24px;
}

.split-mode .editor-area,
.split-mode .preview-area {
  flex: 1;
  min-width: 0;
}

.editor-area :deep(.ant-input) {
  border: none;
  resize: none;
  font-size: 16px;
  line-height: 1.8;
  padding: 0;
  height: auto;
  min-height: calc(100vh - 200px);
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
}

.editor-area :deep(.ant-input):focus {
  box-shadow: none;
}

.markdown-content {
  font-size: 16px;
  line-height: 1.8;
  color: #252933;
  padding: 0 24px;
}

.markdown-content :deep(pre) {
  margin: 16px 0;
  padding: 16px;
  background-color: #282c34;
  border-radius: 6px;
  overflow: auto;
}

.markdown-content :deep(pre code) {
  padding: 0;
  background: none;
  color: #abb2bf;
}

.markdown-content :deep(code) {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 14px;
  padding: 2px 6px;
  background: #f6f8fa;
  border-radius: 3px;
  color: #476582;
}

.markdown-content :deep(pre code.hljs) {
  padding: 0;
  color: #abb2bf;
}

.markdown-content :deep(pre code.hljs .hljs-keyword) {
  color: #c678dd;
}

.markdown-content :deep(pre code.hljs .hljs-string) {
  color: #98c379;
}

.markdown-content :deep(pre code.hljs .hljs-number) {
  color: #d19a66;
}

.markdown-content :deep(pre code.hljs .hljs-function) {
  color: #61afef;
}

.markdown-content :deep(pre code.hljs .hljs-comment) {
  color: #5c6370;
  font-style: italic;
}

.markdown-content :deep(pre code.hljs .hljs-title) {
  color: #61afef;
}

.markdown-content :deep(pre code.hljs .hljs-params) {
  color: #abb2bf;
}

.markdown-content :deep(pre code.hljs .hljs-built_in) {
  color: #e6c07b;
}

.markdown-content :deep(h1),
.markdown-content :deep(h2),
.markdown-content :deep(h3) {
  margin-top: 24px;
  margin-bottom: 16px;
  font-weight: 600;
  line-height: 1.25;
  border-bottom: 1px solid #eaecef;
  padding-bottom: 0.3em;
}

.markdown-content :deep(h1) {
  font-size: 2em;
}

.markdown-content :deep(h2) {
  font-size: 1.5em;
}

.markdown-content :deep(h3) {
  font-size: 1.25em;
}

.markdown-content :deep(p) {
  margin: 16px 0;
  line-height: 1.7;
}

.markdown-content :deep(ul),
.markdown-content :deep(ol) {
  padding-left: 2em;
  margin: 16px 0;
}

.markdown-content :deep(li) {
  margin: 8px 0;
}

.markdown-content :deep(blockquote) {
  margin: 16px 0;
  padding: 0 16px;
  color: #6a737d;
  border-left: 4px solid #dfe2e5;
}

.markdown-content :deep(img) {
  max-width: 100%;
  border-radius: 4px;
  margin: 16px 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.markdown-content :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin: 16px 0;
}

.markdown-content :deep(th),
.markdown-content :deep(td) {
  border: 1px solid #dfe2e5;
  padding: 8px 12px;
}

.markdown-content :deep(th) {
  background-color: #f6f8fa;
}

.back-to-top {
  position: fixed;
  right: 40px;
  bottom: 40px;
  width: 40px;
  height: 40px;
  background-color: #fff;
  border-radius: 50%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s;
  z-index: 99;
}

.back-to-top:hover {
  background-color: #f0f0f0;
  transform: translateY(-2px);
}

.back-to-top .anticon {
  font-size: 20px;
  color: #666;
}

.shortcut-help {
  max-height: 400px;
  overflow-y: auto;
}

.shortcut-table {
  width: 100%;
  border-collapse: collapse;
}

.shortcut-table th,
.shortcut-table td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #e8e8e8;
}

.shortcut-table th {
  background-color: #fafafa;
  font-weight: 500;
}

.shortcut-table tr:hover {
  background-color: #fafafa;
}

kbd {
  display: inline-block;
  padding: 3px 6px;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 12px;
  color: #444d56;
  background-color: #fafbfc;
  border: 1px solid #d1d5da;
  border-bottom-color: #c6cbd1;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #c6cbd1;
}
</style> 